#include <Debug.h>
#include <IDT.h>
#include <IRQ.h>
#include <Proc.h>
#include <string.h>

IDTDescriptor IDT::Table[256];

void IDT::Init() {
	memset(Table, 0, sizeof(IDTDescriptor) * 256 - 1);

	SetDesc(0, isr0);
	SetDesc(1, isr1);
	SetDesc(2, isr2);
	SetDesc(3, isr3);
	SetDesc(4, isr4);
	SetDesc(5, isr5);
	SetDesc(6, isr6);
	SetDesc(7, isr7);
	SetDesc(8, isr8);
	SetDesc(9, isr9);
	SetDesc(10, isr10);
	SetDesc(11, isr11);
	SetDesc(12, isr12);
	SetDesc(13, isr13);
	SetDesc(14, isr14);
	SetDesc(15, isr15);
	SetDesc(16, isr16);
	SetDesc(17, isr17);
	SetDesc(18, isr18);
	SetDesc(19, isr19);
	SetDesc(20, isr20);
	SetDesc(21, isr21);
	SetDesc(22, isr22);
	SetDesc(23, isr23);
	SetDesc(24, isr24);
	SetDesc(25, isr25);
	SetDesc(26, isr26);
	SetDesc(27, isr27);
	SetDesc(28, isr28);
	SetDesc(29, isr29);
	SetDesc(30, isr30);
	SetDesc(31, isr31);
	SetDesc(32, isr32);
	SetDesc(33, isr33);
	SetDesc(34, isr34);
	SetDesc(35, isr35);
	SetDesc(36, isr36);
	SetDesc(37, isr37);
	SetDesc(38, isr38);
	SetDesc(39, isr39);
	SetDesc(40, isr40);
	SetDesc(41, isr41);
	SetDesc(42, isr42);
	SetDesc(43, isr43);
	SetDesc(44, isr44);
	SetDesc(45, isr45);
	SetDesc(46, isr46);
	SetDesc(47, isr47);
	SetDesc(48, isr48);
	SetDesc(49, isr49);
	SetDesc(50, isr50);
	SetDesc(51, isr51);
	SetDesc(52, isr52);
	SetDesc(53, isr53);
	SetDesc(54, isr54);
	SetDesc(55, isr55);
	SetDesc(56, isr56);
	SetDesc(57, isr57);
	SetDesc(58, isr58);
	SetDesc(59, isr59);
	SetDesc(60, isr60);
	SetDesc(61, isr61);
	SetDesc(62, isr62);
	SetDesc(63, isr63);
	SetDesc(64, isr64);
	SetDesc(65, isr65);
	SetDesc(66, isr66);
	SetDesc(67, isr67);
	SetDesc(68, isr68);
	SetDesc(69, isr69);
	SetDesc(70, isr70);
	SetDesc(71, isr71);
	SetDesc(72, isr72);
	SetDesc(73, isr73);
	SetDesc(74, isr74);
	SetDesc(75, isr75);
	SetDesc(76, isr76);
	SetDesc(77, isr77);
	SetDesc(78, isr78);
	SetDesc(79, isr79);
	SetDesc(80, isr80);
	SetDesc(81, isr81);
	SetDesc(82, isr82);
	SetDesc(83, isr83);
	SetDesc(84, isr84);
	SetDesc(85, isr85);
	SetDesc(86, isr86);
	SetDesc(87, isr87);
	SetDesc(88, isr88);
	SetDesc(89, isr89);
	SetDesc(90, isr90);
	SetDesc(91, isr91);
	SetDesc(92, isr92);
	SetDesc(93, isr93);
	SetDesc(94, isr94);
	SetDesc(95, isr95);
	SetDesc(96, isr96);
	SetDesc(97, isr97);
	SetDesc(98, isr98);
	SetDesc(99, isr99);
	SetDesc(100, isr100);
	SetDesc(101, isr101);
	SetDesc(102, isr102);
	SetDesc(103, isr103);
	SetDesc(104, isr104);
	SetDesc(105, isr105);
	SetDesc(106, isr106);
	SetDesc(107, isr107);
	SetDesc(108, isr108);
	SetDesc(109, isr109);
	SetDesc(110, isr110);
	SetDesc(111, isr111);
	SetDesc(112, isr112);
	SetDesc(113, isr113);
	SetDesc(114, isr114);
	SetDesc(115, isr115);
	SetDesc(116, isr116);
	SetDesc(117, isr117);
	SetDesc(118, isr118);
	SetDesc(119, isr119);
	SetDesc(120, isr120);
	SetDesc(121, isr121);
	SetDesc(122, isr122);
	SetDesc(123, isr123);
	SetDesc(124, isr124);
	SetDesc(125, isr125);
	SetDesc(126, isr126);
	SetDesc(127, isr127);
	SetDesc(128, isr128);
	SetDesc(129, isr129);
	SetDesc(130, isr130);
	SetDesc(131, isr131);
	SetDesc(132, isr132);
	SetDesc(133, isr133);
	SetDesc(134, isr134);
	SetDesc(135, isr135);
	SetDesc(136, isr136);
	SetDesc(137, isr137);
	SetDesc(138, isr138);
	SetDesc(139, isr139);
	SetDesc(140, isr140);
	SetDesc(141, isr141);
	SetDesc(142, isr142);
	SetDesc(143, isr143);
	SetDesc(144, isr144);
	SetDesc(145, isr145);
	SetDesc(146, isr146);
	SetDesc(147, isr147);
	SetDesc(148, isr148);
	SetDesc(149, isr149);
	SetDesc(150, isr150);
	SetDesc(151, isr151);
	SetDesc(152, isr152);
	SetDesc(153, isr153);
	SetDesc(154, isr154);
	SetDesc(155, isr155);
	SetDesc(156, isr156);
	SetDesc(157, isr157);
	SetDesc(158, isr158);
	SetDesc(159, isr159);
	SetDesc(160, isr160);
	SetDesc(161, isr161);
	SetDesc(162, isr162);
	SetDesc(163, isr163);
	SetDesc(164, isr164);
	SetDesc(165, isr165);
	SetDesc(166, isr166);
	SetDesc(167, isr167);
	SetDesc(168, isr168);
	SetDesc(169, isr169);
	SetDesc(170, isr170);
	SetDesc(171, isr171);
	SetDesc(172, isr172);
	SetDesc(173, isr173);
	SetDesc(174, isr174);
	SetDesc(175, isr175);
	SetDesc(176, isr176);
	SetDesc(177, isr177);
	SetDesc(178, isr178);
	SetDesc(179, isr179);
	SetDesc(180, isr180);
	SetDesc(181, isr181);
	SetDesc(182, isr182);
	SetDesc(183, isr183);
	SetDesc(184, isr184);
	SetDesc(185, isr185);
	SetDesc(186, isr186);
	SetDesc(187, isr187);
	SetDesc(188, isr188);
	SetDesc(189, isr189);
	SetDesc(190, isr190);
	SetDesc(191, isr191);
	SetDesc(192, isr192);
	SetDesc(193, isr193);
	SetDesc(194, isr194);
	SetDesc(195, isr195);
	SetDesc(196, isr196);
	SetDesc(197, isr197);
	SetDesc(198, isr198);
	SetDesc(199, isr199);
	SetDesc(200, isr200);
	SetDesc(201, isr201);
	SetDesc(202, isr202);
	SetDesc(203, isr203);
	SetDesc(204, isr204);
	SetDesc(205, isr205);
	SetDesc(206, isr206);
	SetDesc(207, isr207);
	SetDesc(208, isr208);
	SetDesc(209, isr209);
	SetDesc(210, isr210);
	SetDesc(211, isr211);
	SetDesc(212, isr212);
	SetDesc(213, isr213);
	SetDesc(214, isr214);
	SetDesc(215, isr215);
	SetDesc(216, isr216);
	SetDesc(217, isr217);
	SetDesc(218, isr218);
	SetDesc(219, isr219);
	SetDesc(220, isr220);
	SetDesc(221, isr221);
	SetDesc(222, isr222);
	SetDesc(223, isr223);
	SetDesc(224, isr224);
	SetDesc(225, isr225);
	SetDesc(226, isr226);
	SetDesc(227, isr227);
	SetDesc(228, isr228);
	SetDesc(229, isr229);
	SetDesc(230, isr230);
	SetDesc(231, isr231);
	SetDesc(232, isr232);
	SetDesc(233, isr233);
	SetDesc(234, isr234);
	SetDesc(235, isr235);
	SetDesc(236, isr236);
	SetDesc(237, isr237);
	SetDesc(238, isr238);
	SetDesc(239, isr239);
	SetDesc(240, isr240);
	SetDesc(241, isr241);
	SetDesc(242, isr242);
	SetDesc(243, isr243);
	SetDesc(244, isr244);
	SetDesc(245, isr245);
	SetDesc(246, isr246);
	SetDesc(247, isr247);
	SetDesc(248, isr248);
	SetDesc(249, isr249);
	SetDesc(250, isr250);
	SetDesc(251, isr251);
	SetDesc(252, isr252);
	SetDesc(253, isr253);
	SetDesc(254, isr254);
	SetDesc(255, isr255);

	struct {
		word limit;
		dword base;
	} __attribute__ ((packed)) GDTR = { 2047, (dword) &Table };
	
	asm volatile ("LIDT	(%0)"
			:
			:"a" (&GDTR));
}

void IDT::SetDesc(int index, void (*addr)()) {
	Table[index].OffsetLow = (dword) addr & 0xFFFF;
	Table[index].OffsetHigh = (dword) addr >> 16;
	Table[index].Selector = 8;
	Table[index].Attribute = 0x8E;
}

extern "C" CPUContext *CHandler(CPUContext *ctx) {
	if (ctx->int_no < 0x20) {
//		Exceptions::Exec(ctx);
	} else if ((ctx->int_no >= 0x20) && (ctx->int_no < 0x30)) {
		IRQ::Exec(ctx);
		if (ctx->int_no == 0x20) {
			if (Scheduler::Initialized) {
				if (!Scheduler::Current->ctx_not_save) {
					Scheduler::Current->ctx = ctx;
				} else {
					Scheduler::Current->ctx_not_save = 0;
				}
				Scheduler::Schedule();
				ctx = Scheduler::Current->ctx;
			}
		}
	}
	
	return ctx;
}
